<?php
/** 
 * @package AMFramework
 * @subpackage Security
 * @author Marcu Alexandru
 * @version 1.0 $Build 305b  
 */
defined('_INDEX') or die('Restricted');

/** Pentru oferirea unui nivel acceptabil de securitate
 * clasele pentru Request si Input filtering sunt inspirate de 
 * alte resurse/frameworkuri publicate sub licenta GPL si mentionate
 * in locurile potrivite;
 */
$GLOBALS['_FWREQUEST'] = array();

define('REQ_NOTRIM', 1);
define('REQ_SAFEHTML', 2);
define('REQ_RAWHTML', 4);

class Amfw_Request {
	// Clasa statica ce se foloseste ca utilitar pentru manevrarea
	// requesturilor; are nevoie de imbunatatiri si documentare
	// pentru ca requesturile sa fie manevrate cat mai sigur (vazut Joomla/Zend)
	// Public =================================================================
	public static function get( $hash = 'default', $mask = 0 ) {
 
		$hash = strtoupper( $hash );
		
		if($hash == 'METHOD') {
			$hash = strtoupper( $_SERVER['REQUEST_METHOD'] );
		}
		
		// Trebuie extinsa functionalitatea si pentru celelalte superglobale;
		switch( $hash ) {
			case 'GET'	:	$input = $_GET;		break;
			case 'POST'	:	$input = $_POST;	break;
			case 'COOKIE':	$input = $_COOKIE;	break;
			case 'FILES':	$input = $_FILES;	break;
			case 'ENV'	:	$input =& $_ENV;	break;
			case 'SERVER':	$input =& $_SERVER;	break;
			default:	$input = $_REQUEST;		break;
		}
		
		$result = Amfw_Request::_cleanvar($input, $mask);
		
		if(get_magic_quotes_gpc())
			$result = self::_stripslashes($result);

		return $result;
	}
	
	/**
	 * @param unknown_type $array
	 * @param unknown_type $hash
	 * @param unknown_type $overwrite
	 */
	public static function set( $array, $hash = 'method', $overwrite = true ) 
	{
		foreach($array as $key => $value) { 
			self::setv($key, $value, $hash, $overwrite);
		}
	}
	
	/**
	 * @param unknown_type $name
	 * @param unknown_type $default
	 * @param unknown_type $hash
	 * @param unknown_type $mask
	 * @return Ambigous <Mixed, unknown, multitype:>
	 * @copyright	Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
 	 * @license		GNU/GPL, see LICENSE.php
	 */
	public static function getv( $name, $default = null, $hash = 'default', $mask = 0 ) 
	{
		// Ensure hash and type are uppercase
		$hash = strtoupper( $hash );
		if ($hash === 'METHOD') {
			$hash = strtoupper( $_SERVER['REQUEST_METHOD'] );
		}

		$sig = $hash.$mask;

		// Get the input hash
		switch ($hash)
		{
			case 'GET' :
				$input = &$_GET;
				break;
			case 'POST' :
				$input = &$_POST;
				break;
			case 'FILES' :
				$input = &$_FILES;
				break;
			case 'COOKIE' :
				$input = &$_COOKIE;
				break;
			case 'ENV'    :
				$input = &$_ENV;
				break;
			case 'SERVER'    :
				$input = &$_SERVER;
				break;
			default:
				$input = &$_REQUEST;
				$hash = 'REQUEST';
				break;
		}

		if (isset($GLOBALS['_FWREQUEST'][$name]['SET.'.$hash]) && ($GLOBALS['_FWREQUEST'][$name]['SET.'.$hash] === true)) {
			// Get the variable from the input hash
			$var = (isset($input[$name]) && $input[$name] !== null) ? $input[$name] : $default;
			$var = self::_cleanvar($var, $mask);
		}
		elseif (!isset($GLOBALS['_FWREQUEST'][$name][$sig]))
		{
			if (isset($input[$name]) && $input[$name] !== null) {
				// Get the variable from the input hash and clean it
				$var = self::_cleanvar($input[$name], $mask);

				// Handle magic quotes compatability
				if (get_magic_quotes_gpc() && ($var != $default) && ($hash != 'FILES')) {
					$var = self::_stripslashes( $var );
				}

				$GLOBALS['_FWREQUEST'][$name][$sig] = $var;
			}
			elseif ($default !== null) {
				// Clean the default value
				$var = self::_cleanvar($default, $mask);
			}
			else {
				$var = $default;
			}
		} else {
			$var = $GLOBALS['_FWREQUEST'][$name][$sig];
		}

		return $var;
	}
	
	/**
	 * @param unknown_type $var
	 * @param unknown_type $value
	 * @param unknown_type $hash
	 * @param unknown_type $overwrite
	 * @copyright	Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
 	 * @license		GNU/GPL, see LICENSE.php
	 */
	public static function setv( $var, $value, $hash = 'method', $overwrite = true ) 
	{
		//If overwrite is false and the var exists, it will just return this one
		if(!$overwrite && array_key_exists($var, $_REQUEST)) {
			return $_REQUEST[$var];
		}

		// Clean global request var
		$GLOBALS['_FWREQUEST'][$var] = array();

		// Get the request hash value
		$hash = strtoupper($hash);
		if ($hash === 'METHOD') {
			$hash = strtoupper($_SERVER['REQUEST_METHOD']);
		}

		$previous	= array_key_exists($var, $_REQUEST) ? $_REQUEST[$var] : null;

		switch ($hash)
		{
			case 'GET' :
				$_GET[$var] = $value;
				$_REQUEST[$var] = $value;
				break;
			case 'POST' :
				$_POST[$var] = $value;
				$_REQUEST[$var] = $value;
				break;
			case 'COOKIE' :
				$_COOKIE[$var] = $value;
				$_REQUEST[$var] = $value;
				break;
			case 'FILES' :
				$_FILES[$var] = $value;
				break;
			case 'ENV'    :
				$_ENV['name'] = $value;
				break;
			case 'SERVER'    :
				$_SERVER['name'] = $value;
				break;
		}

		// Mark this variable as 'SET'
		$GLOBALS['_FWREQUEST'][$var]['SET.'.$hash] = true;
		$GLOBALS['_FWREQUEST'][$var]['SET.REQUEST'] = true;

		return $previous;
	}
	
	public static function method() 
	{
		$method = strtoupper( $_SERVER['REQUEST_METHOD'] );
		return $method;	
	}
	
	/**
	 * Cleans the request from script injection.
	 *
	 * @static
	 * @return	void
	 * @since	1.5
	 * @copyright	Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
 	 * @license		GNU/GPL, see LICENSE.php
	 */
	public static function clean() {
		Amfw_Request::_cleanarr( $_FILES );
		Amfw_Request::_cleanarr( $_ENV );
		Amfw_Request::_cleanarr( $_GET );
		Amfw_Request::_cleanarr( $_POST );
		Amfw_Request::_cleanarr( $_COOKIE );
		Amfw_Request::_cleanarr( $_SERVER );

		if (isset( $_SESSION )) {
			Amfw_Request::_cleanarr( $_SESSION );
		}

		$REQUEST	= $_REQUEST;
		$GET		= $_GET;
		$POST		= $_POST;
		$COOKIE		= $_COOKIE;
		$FILES		= $_FILES;
		$ENV		= $_ENV;
		$SERVER		= $_SERVER;

		if (isset ( $_SESSION )) {
			$SESSION = $_SESSION;
		}

		foreach ($GLOBALS as $key => $value)
		{
			if ( $key != 'GLOBALS' ) {
				unset ( $GLOBALS [ $key ] );
			}
		}
		$_REQUEST	= $REQUEST;
		$_GET		= $GET;
		$_POST		= $POST;
		$_COOKIE	= $COOKIE;
		$_FILES		= $FILES;
		$_ENV 		= $ENV;
		$_SERVER 	= $SERVER;

		if (isset ( $SESSION )) {
			$_SESSION = $SESSION;
		}
		
		// Make sure the request hash is clean on file inclusion
		$GLOBALS['_FWREQUEST'] = array();
	}
	
	public static function checkToken() {
		$session	=& Amfw_Factory::getSession();
		$sess_token	= $session->getToken();	// Challenge token(din sesiune)
		$post_token	= Amfw_Request::getv('token',null);	//Posted token
		
		if($sess_token === $post_token) 
		{
			return true;
		}
		else 
		{
			var_dump($sess_token); echo '<br>';
			var_dump($post_token);
			return false;	//Invalid token: the implementation should kill the session here
		}
		
	}
	
	// Private ================================================================
	
	/**
	 * Adds an array to the GLOBALS array and checks that the GLOBALS variable is not being attacked
	 *
	 * @access	protected
	 * @param	array	$array	Array to clean
	 * @param	boolean	True if the array is to be added to the GLOBALS
	 * @since	1.5
	 * @copyright	Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
 	 * @license		GNU/GPL, see LICENSE.php
	 */
	private static function _cleanarr( $array, $globalise = false ) 
	{
		static $banned = array( '_files', '_env', '_get', '_post', '_cookie', '_server', '_session', 'globals' );

		foreach ($array as $key => $value)
		{
			// PHP GLOBALS injection bug
			$failed = in_array( strtolower( $key ), $banned );

			// PHP Zend_Hash_Del_Key_Or_Index bug
			$failed |= is_numeric( $key );
			if ($failed) {
				die( 'Illegal variable <b>' . implode( '</b> or <b>', $banned ) . '</b> passed to script.' );
			}
			if ($globalise) {
				$GLOBALS[$key] = $value;
			}
		}
	}
	
	/** Uses the Amfw_InputFilter to clean the Request
	 * 
	 *  @access private
	 * @param Mixed $var - variable or array to be filtered
	 * @param int $mask - flag used for filtering
	 * @return Mixed $var - the cleaned string or Array of strings 
	 */
	private static function _cleanvar( $var, $mask ) 
	{
		static $filter;
		
		$filter = isset( $filter ) ? $filter : Amfw_InputFilter::getInstance();
		
		// Input filtering
		switch( $mask )
		{
			case REQ_RAWHTML:
				// If the allow raw flag is set, don't alter the variable
				break;
				
			case REQ_SAFEHTML:
				// If the allow html flag is set, apply a safe html filter to the var
				$filter->init(null, null, 1, 1);
				$var = $filter->process($var);
				break;

			default:
				// Since no allow flags were set, we will apply the 
				// most strict filter to the variable
				$filter->init( );
				$var = $filter->process($var);
				break;
		}
		
		// If the trim flag is not set, we trim the var;
		if( $mask != REQ_NOTRIM ) 
		{
			Amfw_Utils::trim( $value );
		}
		
		return $var;
	}
	
	// Should probably be moved to Amfw_Utility for reuse
	/** Recursive trimming method to use for arrays and strings
	 * The passed var is trimmed 
	 * 
	 * @param Mixed $var Array or string to be trimmed
	 */
/*	public static function _trim( &$var ) {
		if(is_string( $var )): $var = trim( $var ); endif;
		if(is_array( $var )):
			foreach($var as &$value) {
				Amfw_Utils::trim( $value );
			}
		endif;
	}*/
	
	private static function _stripslashes( $value ) {
		if(is_array( $value )):
			return array_map( array('Amfw_Request', '_stripSlashes'), $value);
		else: return stripslashes( $value );
		endif;
	}
	
}